#pragma once

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

//#define Myself 1

const std::string space_sep = " ";
const std::string protocol_sep = "\n";
// 封装报头    "len"\n"x op y"\n
std::string Encode(std::string &content)
{
    std::string package = std::to_string(content.size());
    package += protocol_sep;
    package += content;
    package += protocol_sep;
    return package;
}
// 截取有效载荷  "len"\n"x op y"\n
bool Decode(std::string &package, std::string *content)
{
    std::size_t pos = package.find(protocol_sep);
    if (pos == std::string::npos)
        return false;
    std::string len_str = package.substr(0, pos);
    std::size_t len = std::stoi(len_str);
    // package = left_str + content_str + 2
    std::size_t total_len = len_str.size() + len + 2;
    if (package.size() < total_len)
        return false;
    *content = package.substr(pos + 1, len);
    package.erase(0, total_len);
    return true;
}
class Request
{
public:
    Request(int data1, int data2, char oper) : x_(data1), y_(data2), op_(oper)
    {
    }
    Request()
    {
    }
    ~Request()
    {
    }

public:
    bool Serialize(std::string *out)
    {
#ifdef MySelf
        // 序列化为 "len"\n"x op y"
        // 1.报文的有效载荷
        std::string str = std::to_string(x_);
        str += space_sep;
        str += op_;
        str += space_sep;
        str += std::to_string(y_);
        *out = str;
        return true;
#else
        Json::Value root;
        root["x"] = x_;
        root["y"] = y_;
        root["op"] = op_;
        // Json::FastWriter w;
        Json::StyledWriter w;
        *out = w.write(root);
        return true;
#endif
    }
    bool Deserialize(const std::string &in)
    {
#ifdef MySelf
        // "x op y"
        std::size_t left = in.find(space_sep);
        if (left == std::string::npos)
            return false;
        std::string part_x = in.substr(0, left);

        std::size_t right = in.rfind(space_sep);
        if (right == std::string::npos)
            return false;
        std::string part_y = in.substr(right + 1);

        if (left + 2 != right)
            return false;
        op_ = in[left + 1];
        x_ = std::stoi(part_x);
        y_ = std::stoi(part_y);
#else
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);

        x_ = root["x"].asInt();
        y_ = root["y"].asInt();
        op_ = root["op"].asInt();
        return true;
#endif
    }
    void DebugPrint()
    {
        std::cout << "新请求构建完成:x = " << x_ << op_ << y_ << "= ?" << std::endl;
    }

public:
    int x_;
    int y_;
    char op_;
};

class Response
{
public:
    Response(int result, int code) : result_(result), code_(code)
    {
    }
    Response()
    {
    }
    ~Response()
    {
    }

public:
    bool Serialize(std::string *out)
    {
#ifdef MySelf
        // 序列化为 "len"\n"result code"
        // 1.报文的有效载荷
        std::string str = std::to_string(result_);
        str += space_sep;
        str += code_;
        *out = str;
        return true;
#else
        Json::Value root;
        root["result"] = result_;
        root["code"] = code_;
        // Json::FastWriter w;
        Json::StyledWriter w;
        *out = w.write(root);
        return true;
#endif
    }
    bool Deserialize(std::string &in)
    {
#ifdef MySelf
        std::size_t pos = in.find(space_sep);
        if (pos == std::string::npos)
            return false;
        std::string part_left = in.substr(0, pos);
        std::string part_right = in.substr(pos + 1);
        result_ = stoi(part_left);
        code_ = stoi(part_right);
#else
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);

        result_ = root["result"].asInt();
        code_ = root["code"].asInt();
        return true;
#endif
    }
    void DebugPrint()
    {
        std::cout << "结果响应完成,result: " << result_ << ",code: " << code_ << std::endl;
    }

public:
    int result_;
    int code_;
};
